package com.yth.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.core.util.Separators;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.Type;

/**
 * @author yutianhong
 * @version 1.0
 * @since 2025/5/16 13:56
 */
public class JsonUtils {
    private static final ObjectMapper OBJECT_MAPPER = initializeObjectMapper();
    private static final ObjectMapper OBJECT_MAPPER_WITHOUT_NULLS = initializeObjectMapper()
            .setSerializationInclusion(JsonInclude.Include.NON_NULL);

    /**
     * 将JSON字符串解析为Java对象。
     */
    public static Object parse(String json) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        return ThrowHider.exec(() -> OBJECT_MAPPER.readValue(json, Object.class));
    }

    /**
     * 将JSON字符串解析为Java对象。
     */
    public static <T> T parse(String json, Class<T> valueType) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        return ThrowHider.exec(() -> OBJECT_MAPPER.readValue(json, valueType));
    }

    /**
     * 将JSON字符串解析为Java对象。
     */
    public static <T> T parse(String json, Type valueType) {
        if (StringUtils.isBlank(json)) {
            return null;
        }
        return ThrowHider.exec(() -> OBJECT_MAPPER.readValue(json, OBJECT_MAPPER.getTypeFactory().constructType(valueType)));
    }

    /**
     * 将Java对象序列化为JSON字符串。
     */
    public static String toString(Object obj) {
        return ThrowHider.exec(() -> OBJECT_MAPPER.writeValueAsString(obj));
    }

    /**
     * 将Java对象序列化为格式化的JSON字符串。
     */
    public static String toStringPretty(Object obj) {
        return ThrowHider.exec(() -> OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj));
    }

    /**
     * 将Java对象序列化为JSON字符串，不包含null值。
     */
    public static String toStringWithoutNulls(Object obj) {
        return ThrowHider.exec(() -> OBJECT_MAPPER_WITHOUT_NULLS.writeValueAsString(obj));
    }

    /**
     * 将Java对象序列化为格式化的JSON字符串，不包含null值。
     */
    public static String toStringPrettyWithoutNulls(Object obj) {
        return ThrowHider.exec(() -> OBJECT_MAPPER_WITHOUT_NULLS.writerWithDefaultPrettyPrinter().writeValueAsString(obj));
    }

    private static ObjectMapper initializeObjectMapper() {
        return JsonMapper.builder()
                .configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
                .configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
                .configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true)
                .defaultPrettyPrinter(new DefaultPrettyPrinter()
                        .withArrayIndenter(new DefaultIndenter().withIndent("    "))
                        .withObjectIndenter(new DefaultIndenter().withIndent("    "))
                        .withSeparators(new Separators(Separators.DEFAULT_ROOT_VALUE_SEPARATOR,
                                ':', Separators.Spacing.AFTER,
                                ',', Separators.Spacing.NONE, "",
                                ',', Separators.Spacing.NONE, ""))
                )
                .build();
    }

    private JsonUtils() {
    }
}
